home *** CD-ROM | disk | FTP | other *** search
/ Internet Surfer: Getting Started / Internet Surfer - Getting Started (Wayzata Technology)(7231)(1995).bin / pc / textfile / mac_faqs / xt_faq < prev    next >
Internet Message Format  |  1995-01-30  |  57KB

  1. Xref: bloom-picayune.mit.edu comp.windows.x.intrinsics:622 comp.windows.x:61741 news.answers:4414
  2. Newsgroups: comp.windows.x.intrinsics,comp.windows.x,news.answers
  3. Path: bloom-picayune.mit.edu!enterpoop.mit.edu!usc!zaphod.mps.ohio-state.edu!cis.ohio-state.edu!oboe.cis.ohio-state.edu!ware
  4. From: ware@oboe.cis.ohio-state.edu (Peter Ware)
  5. Subject: comp.windows.x.intrinsics Frequently Asked Questions (FAQ)
  6. Message-ID: <FAQ-Xt_723479548@oboe.cis.ohio-state.edu>
  7. Followup-To: comp.windows.x.intrinsics
  8. Summary: Answers about the X11 Window System widgets and Xt Intrinsics library
  9. Sender: news@cis.ohio-state.edu (NETnews        )
  10. Supersedes: <FAQ-Xt_718402537@oboe.cis.ohio-state.edu>
  11. Reply-To: ware@cis.ohio-state.edu
  12. Organization: The Ohio State University Dept. of Computer and Info. Science
  13. Date: Fri, 4 Dec 1992 14:32:40 GMT
  14. Approved: news-answers-request@MIT.Edu
  15. Expires: Fri, 15 Jan 1993 14:32:28 GMT
  16. Lines: 1347
  17.  
  18. Archive-name: Xt-FAQ
  19. Version: $Id: FAQ-Xt,v 1.18 92/12/04 09:29:38 ware Exp $
  20.  
  21.             The X Toolkit Intrinsics F.A.Q
  22.               A monthly posting
  23.  
  24.  
  25. This article contains the answers to some Frequently Asked Questions
  26. (FAQ) from comp.windows.x about the X Toolkit Intrinsics.  To submit
  27. questions (preferably with an answer) send email to: ware@cis.ohio-state.edu
  28.  
  29. All code fragments are public domain.  
  30.  
  31.                    Contents
  32. 0.  Xt Glossary
  33. 1.  Software Versions
  34. 2.  Related FAQ's
  35. 3.  Why does my application core dump when I use signals/alarms/cthreads?
  36. 4.  How do I use a different visual than the default?
  37. 5.  Which visual should an application use?
  38. 6.  Why do only Shell widgets have a Visual?
  39. 7.  Which visual, depth and colormap do Shells inherit?
  40. 8.  I've done all the above and I still get a BadMatch error.  Why?
  41. 9.  Why doesn't my widget get destroyed when I call XtDestroyWidget()?
  42. 10. How do I exit but still execute the DestroyCallbacks?
  43. 11. How do I resize a Shell widget?
  44. 12. Why can't XtAppAddInput() handle files?
  45. 13. What good books and magazines are there on Xt?
  46. 14. What Widgets are available?
  47. 15. What alternatives to the Intrinsics are there?
  48. 16. How do I pass a float value to XtSetValues?
  49. 17. +++How do I write a resource converter?
  50. 18. How do I open multiple displays?
  51. 19. What changed from R3 to R4 to R5?
  52. 20. Where are the resources loaded from?
  53. 21. What order are callbacks executed in?
  54. 22. How do I know if a widget is visible?
  55. 23. How do I reparent a widget in Xt, i.e. XtReparentWidget()?
  56. 24. Why use XtMalloc, XtFree, etc?
  57. 25. How to debug an Xt application?
  58.  
  59. The "+++" indicates the question needs more of an answer.
  60.  
  61. ----------------------------------------------------------------------
  62. 0.  Xt Glossary
  63. ----------------------------------------------------------------------
  64.  
  65. o The Xt Intrinsics implement an object oriented interface to C code
  66.   to allow useful graphical components to be created.  Included with
  67.   this are classes that provide the base functionality: Object,
  68.   RectObj, Core, Composite, Constraint, Shell, OverrideShell, WMShell,
  69.   etc.  The terms "Xt" and "Intrinsics" are used interchangeably,
  70.   however, they are used very precisely to mean a specific library of the X
  71.   window system.  In particular, it does not include the Athena,
  72.   Motif, OLIT or any other widget set.  Without further widgets the
  73.   Intrinsics are not especially useful.
  74.  
  75. o A widget refers to a user interface abstraction created via Xt.  The
  76.   precise use, is any object that is a subclass of the Core class.  It
  77.   is used loosely to refer to anything that is a subclass of the
  78.   Object class although these are more accurately called windowless
  79.   widgets or gadgets.
  80.  
  81. o Xlib is the C interface to the X11 protocol.  It is one layer below
  82.   the Xt Intrinsics.  Typically a widget uses relatively few Xlib
  83.   functions because Xt provides most such services although an
  84.   understanding of Xlib helps with problems.
  85.  
  86. ----------------------------------------------------------------------
  87. 1.  Software Versions
  88. ----------------------------------------------------------------------
  89.  
  90. The following are the latest versions of Xt based software:
  91.         _____________________________________________________________
  92.     Software    Version        Released    Next Expected
  93.         _____________________________________________________________
  94.     X11R4        patch 18            (none)
  95.     X11R5        patch 17    8/27/92        ??
  96.     Athena Widgets    (see X11R5)
  97.     Motif        1.2.1        9/92        ??
  98.     OLIT        ??        ??        ??
  99.     Xtra        2.5        6/15/92        ??
  100.     Xw        X11R4                (none)
  101.     Xcu        X11R5                (none)
  102.     fwf        3.2        6/08/92        ??
  103.         _____________________________________________________________
  104.  
  105. ----------------------------------------------------------------------
  106. 2.  Related FAQ's
  107. ----------------------------------------------------------------------
  108. David B. Lewis (uunet!craft!faq) maintains the FAQ on X.  It
  109. is posted monthly on comp.windows.x and located on export in contrib/FAQ.
  110.  
  111. Liam R. E. Quin (lee@sq.sq.com) posts an FAQ list on Open Look to 
  112. comp.windows.x.  
  113.  
  114. Jan Newmarch (jan@pandonia.canberra.edu.au) posts an FAQ list on Motif 
  115. to comp.windows.x.motif.
  116.  
  117. Peter Ware (ware@cis.ohio-state.edu) posts an FAQ list for
  118. comp.windows.x.intrinsics; it is on export in contrib/FAQ-Xt.
  119.  
  120. ----------------------------------------------------------------------
  121. 3.  Why does my application core dump when I use signals/alarms/cthreads?
  122. ----------------------------------------------------------------------
  123.  
  124. In brief, Xlib, Xt and most widget sets have no mutual exclusion for
  125. critical sections.  Any interrupt handler is likely to leave one of
  126. the above libraries in an inconsistent state -- such as all the
  127. appropriate flags not yet set, dangling pointers, in the middle of a
  128. list traversal, etc.  Note that the ANSI C standard points out that
  129. behavior of a signal handler is undefined if the signal handler calls
  130. any function other than signal() itself, so this is not a problem
  131. specific to Xlib and Xt; the POSIX specification mentions other
  132. functions which may be called safely but it may not be assumed that
  133. these functions are called by Xlib or Xt functions.
  134.  
  135. The only safe way to deal with signals is to set a flag in the
  136. interrupt handler.  This flag later needs to be checked either by a
  137. work procedure or a timeout callback.  It is incorrect to add either
  138. of these in the interrupt handler.  As another note, it is dangerous
  139. to add a work procedure that never finishes.  This effectively
  140. preempts any work procedures previously added and so they will never
  141. be called.  Another option is to open a pipe, tell the event loop
  142. about the read end using XtAppAddInput() and then the signal handler
  143. can write a byte to the write end of the pipe for each signal.
  144. However, this could deadlock your process if the pipe fills up.
  145.  
  146. Why don't the Intrinsics deal with this problem?  Primarily because it
  147. is supposed to be a portable layer to any hardware and operating
  148. system.   Is that a good enough reason -- I don't think so.
  149.  
  150.         Note: the article in The X Journal 1:4 and the example in O'Reilly
  151. Volume 6 are in error.
  152.  
  153. ----------------------------------------------------------------------
  154. 4.  How do I use a different visual than the default?
  155. ----------------------------------------------------------------------
  156.  
  157. This requires a more complicated answer than it should.  A window has
  158. three things that are visual specific -- the visual, colormap and
  159. border pixmap.  All widgets have their own Colormap and BorderPixmap
  160. resource; only shell widgets have Visual resources (another questions
  161. deals with why shells have a Visual).  The default value of these
  162. resources is CopyFromParent which does exactly what it says.  In the
  163. shell widget CopyFromParent gets evalulated as DefaultVisualOfScreen
  164. and DefaultColormapOfScreen.  When any one of the three resources is
  165. not properly set, a BadMatch error occurs when the window is
  166. created.  They are not properly set because each of the values depends
  167. on the visual being used.  
  168.  
  169. How to get this to work?  There are two parts to the answer.  The
  170. first is if you want an application to start with a particular visual
  171. and the second is if you want a particular shell within an application
  172. to start with a different visual.  The second is actually easier
  173. because the basic information you need is available.  The first is a
  174. little harder because you'll need to initialize much of the toolkit
  175. yourself in order to determine the needed information.
  176.  
  177. /*
  178.  * Some sample code to start up an application using something other
  179.  * than the default visual.
  180.  *
  181.  * To compile:
  182.  *    cc -g visual.c -o visual -lXaw -lXmu -lXt -lXext -lX11 -lm
  183.  *
  184.  * To run:
  185.  *    ./visual -geometry 300x300 -visual StaticColor -fg blue -bg yellow
  186.  *
  187.  * you need to move the mouse to get the particular visuals colormap
  188.  * to install.
  189.  */
  190.  
  191. #include <X11/Intrinsic.h>
  192. #include <X11/StringDefs.h>
  193. #include <X11/Shell.h>
  194.  
  195. typedef struct
  196. {
  197.     Visual    *visual;
  198. } OptionsRec;
  199.  
  200. OptionsRec    Options;
  201.  
  202. XtResource resources[] =
  203. {
  204.     {"visual", "Visual", XtRVisual, sizeof (Visual *),
  205.     XtOffsetOf (OptionsRec, visual), XtRImmediate, NULL},
  206. };
  207.  
  208. XrmOptionDescRec Desc[] =
  209. {
  210.     {"-visual", "*visual", XrmoptionSepArg, NULL}
  211. };
  212.  
  213.  
  214.  
  215. int
  216. main (argc, argv)
  217.     int        argc;
  218.     char        **argv;
  219. {
  220.     XtAppContext    app;        /* the application context */
  221.     Widget        top;        /* toplevel widget */
  222.     Display        *dpy;        /* display */
  223.     char        **xargv;    /* saved argument vector */
  224.     int        xargc;        /* saved argument count */
  225.     Colormap    colormap;    /* created colormap */
  226.     XVisualInfo    vinfo;        /* template for find visual */
  227.     XVisualInfo    *vinfo_list;    /* returned list of visuals */
  228.     int        count;        /* number of matchs (only 1?) */
  229.     Arg        args[10];
  230.     Cardinal    cnt;
  231.     char        *name = "test";
  232.     char        *class = "Test";
  233.  
  234.     /*
  235.      * save the command line arguments
  236.      */
  237.  
  238.     xargc = argc;
  239.     xargv = (char **) XtMalloc (argc * sizeof (char *));
  240.     bcopy ((char *) argv, (char *) xargv, argc * sizeof (char *));
  241.  
  242.     /*
  243.      * The following creates a _dummy_ toplevel widget so we can
  244.      * retrieve the appropriate visual resource.
  245.      */
  246.     cnt = 0;
  247.     top = XtAppInitialize (&app, class, Desc, XtNumber (Desc), &argc, argv,
  248.                    (String *) NULL, args, cnt);
  249.     dpy = XtDisplay (top);
  250.     cnt = 0;
  251.     XtGetApplicationResources (top, &Options, resources,
  252.                    XtNumber (resources),
  253.                    args, cnt);
  254.     cnt = 0;
  255.     if (Options.visual && Options.visual != DefaultVisualOfScreen (XtScreen (top)))
  256.     {
  257.         XtSetArg (args[cnt], XtNvisual, Options.visual); ++cnt;
  258.         /*
  259.          * Now we create an appropriate colormap.  We could
  260.          * use a default colormap based on the class of the
  261.          * visual; we could examine some property on the
  262.          * rootwindow to find the right colormap; we could
  263.          * do all sorts of things...
  264.          */
  265.         colormap = XCreateColormap (dpy,
  266.                         RootWindowOfScreen (XtScreen (top)),
  267.                         Options.visual,
  268.                         AllocNone);
  269.         XtSetArg (args[cnt], XtNcolormap, colormap); ++cnt;
  270.  
  271.         /*
  272.          * Now find some information about the visual.
  273.          */
  274.         vinfo.visualid = XVisualIDFromVisual (Options.visual);
  275.         vinfo_list = XGetVisualInfo (dpy, VisualIDMask, &vinfo, &count);
  276.         if (vinfo_list && count > 0)
  277.         {
  278.             XtSetArg (args[cnt], XtNdepth, vinfo_list[0].depth);
  279.             ++cnt;
  280.             XFree ((XPointer) vinfo_list);
  281.         }
  282.     }
  283.     XtDestroyWidget (top);
  284.  
  285.  
  286.     /*
  287.      * Now create the real toplevel widget.
  288.      */
  289.     XtSetArg (args[cnt], XtNargv, xargv); ++cnt;
  290.     XtSetArg (args[cnt], XtNargc, xargc); ++cnt;
  291.     top = XtAppCreateShell ((char *) NULL, class,
  292.                 applicationShellWidgetClass,
  293.                 dpy, args, cnt);
  294.  
  295.     /*
  296.      * Display the application and loop handling all events.
  297.      */
  298.     XtRealizeWidget (top);
  299.     XtAppMainLoop (app);
  300.     return (0);
  301. }
  302.  
  303. ----------------------------------------------------------------------
  304. 5.  Which visual should an application use?
  305. ----------------------------------------------------------------------
  306.  
  307. This is a point that can be argued about but one opinion is there is
  308. no way for an application to know the appropriate visual -- it has to
  309. be specified by the user.  If you disagree with this then your
  310. application probably falls into the category of always using the
  311. default visual or it is hardware specific and expects some particular
  312. visual such as 24bit TrueColor with an OverlayPlane extension (or some
  313. such).
  314.  
  315. Why?  No application runs in isolation.  Depending on the way a server
  316. allocates resources I may not always want your application to run in
  317. TrueColor mode if it is going to mess up my other applications.  I may
  318. be very upset if it chooses to run in GreyScale instead of PsuedoColor
  319. or just monochrome.
  320.  
  321. As an example, on a low end color Sun server there are many different
  322. possible visuals: monochrome, 256 entry colormap, static gray, static
  323. color, and a 3/3/2 TrueColor.  The SGI Iris's offer all the above 
  324. plus 12 bit TrueColor, 24 bit TrueColor, an Overlay Plane.
  325.  
  326. ----------------------------------------------------------------------
  327. 6.  Why do only Shell widgets have a Visual?
  328. ----------------------------------------------------------------------
  329.  
  330. This is strictly by convention.  It makes it possible for an arbitrary
  331. widget to know that the visual it uses can be found by looking for the
  332. shell widget that is its ancestor and obtaining the visual of that
  333. shell.
  334.  
  335. A widget can have its own visual resource.  If it does, it must have
  336. its own realize method to use the visual when it calls
  337. XCreateWindow().  You should also make this a resource that can be
  338. obtained with XtGetValues() so other widgets can find it.  A
  339. reasonable value is probably XtNvisual.
  340.  
  341. ----------------------------------------------------------------------
  342. 7.  Which visual, depth and colormap do Shells inherit?
  343. ----------------------------------------------------------------------
  344.  
  345. The default value for these resources are set to CopyFromParent.  This
  346. is interpreted as the DefaultColormapOfScreen(), DefaultDepthOfScreen()
  347. and the default visual of the screen if the widget has no parent -- i.e.
  348. it is an applicationShellWidgetClass and the root of your widget tree.
  349.  
  350. If the parent of the widget is not null, then the shell copies
  351. colormap and depth from its parent and uses CopyFromParent as the
  352. visual.
  353.  
  354. ----------------------------------------------------------------------
  355. 8.  I've done all the above and I still get a BadMatch error.  Why?
  356. ----------------------------------------------------------------------
  357.  
  358. Some resource converters improperly cache references.  This was
  359. especially true of X11R3 and earlier versions of Motif.
  360.  
  361. ----------------------------------------------------------------------
  362. 9.  Why doesn't my widget get destroyed when I call XtDestroyWidget()?
  363. ----------------------------------------------------------------------
  364.  
  365. See section 2.8 of the Xt specification.
  366.  
  367. It eventually does get destroyed, just not immediately.  The
  368. Intrinsics destroy a widget in a two-phase process.  First it and all
  369. of its children have a flag set that indicate it is being destroyed.
  370. It is then put on a list of widgets to be destroyed.  This way any
  371. pending X events or further references to that widget can be cleaned
  372. up before the memory is actually freed.  The second phase is then
  373. performed after all callbacks, event handlers, and actions have
  374. completed, before checking for the next X event.  At this point the
  375. list is traversed and each widget's memory is actually free()'d, among
  376. other things.
  377.  
  378. As some further caveats/trivia, the widgets may be destroyed if the
  379. Intrinsics determine that they have no further references to the
  380. widgets on the list.  If so, then the phase 2 destruction occurs
  381. immediately.  Also, if nested event loops are used, widgets placed on
  382. the destroy list before entering the inner event loop are not
  383. destroyed until returning to the outer event loop.
  384.  
  385. ----------------------------------------------------------------------
  386. 10. How do I exit but still execute the DestroyCallbacks?
  387. ----------------------------------------------------------------------
  388.  
  389. The problem is if a simple and entirely reasonable approach to exiting
  390. an application is used, such as calling exit() directly, then a widget
  391. may not have a chance to clean up any external state -- such as open
  392. sockets, temporary files, allocated X resources, etc.  (this code for
  393. simplicity reasons assumes only a single toplevel widget):
  394.  
  395.  
  396.     Widget
  397.     ToplevelGet (gw)
  398.         Widget        gw;        /* widget to find toplevel */
  399.     {
  400.         Widget        top;
  401.  
  402.         for (top = gw; XtParent (top); top = XtParent (top))
  403.             /* empty */;
  404.         return (top);
  405.     }
  406.  
  407.     void
  408.     ExitCallback (gw, closure, call_data)
  409.         Widget        gw;        /* widget */
  410.         XtPointer    closure;    /* data the app specified */
  411.         XtPointer    call_data;    /* widget specific data */
  412.     {
  413.         Widget        toplevel;
  414.  
  415.         toplevel = ToplevelGet (gw);
  416.         XtUnmapWidget (toplevel);    /* make it disappear quickly */
  417.         XtDestroyWidget (toplevel);
  418.         exit (0);
  419.     }
  420.  
  421. One can see that the above code exit's immediately after destroying
  422. the toplevel widget.  The trouble is the phase 2 destruction may never
  423. occur.  
  424.  
  425. This works for most widgets and most applications but will not work
  426. for those widgets that have any external state.  You might think that
  427. since it works now it will always work but remember that part of the
  428. reason an object oriented approach is used is so one can be ignorant
  429. of the implementation details for each widget.  Which means that the
  430. widget may change and someday require that some external state is
  431. cleaned up by the Destroy callbacks.
  432.  
  433. One alternative is to modify ExitCallback() to set a global flag and
  434. then test for that flag in a private event loop.  However, private
  435. event loops are frowned upon because it tends to encourage sloppy, and
  436. difficult to maintain practices.
  437.  
  438. Try the following code instead.
  439.  
  440.     #include <X11/Intrinsic.h>
  441.  
  442.     extern Widget ToplevelGet (
  443.     #if NeedFunctionPrototypes
  444.         Widget        gw
  445.     #endif
  446.     );
  447.  
  448.     extern Boolean ExitWorkProc (
  449.     #if NeedFunctionPrototypes
  450.         XtPointer    closure
  451.     #endif
  452.     );
  453.  
  454.     extern void ExitCallback (
  455.     #if NeedFunctionPrototypes
  456.         Widget        gw,
  457.         XtPointer    closure,
  458.         XtPointer    call_data
  459.     #endif
  460.     );
  461.  
  462.     Widget
  463.     ToplevelGet (gw)
  464.     Widget        gw;        /* widget to find toplevel */
  465.     {
  466.         Widget        top;
  467.  
  468.         for (top = gw; XtParent (top); top = XtParent (top))
  469.             /* empty */;
  470.         return (top);
  471.     }
  472.  
  473.  
  474.     void
  475.     ExitCallback (gw, closure, call_data)
  476.     Widget        gw;        /* widget */
  477.     XtPointer    closure;    /* data the app specified */
  478.     XtPointer    call_data;    /* widget specific data */
  479.     {
  480.         Widget        toplevel;
  481.  
  482.         toplevel = ToplevelGet (gw);
  483.         XtUnmapWidget (toplevel);    /* make it disappear quickly */
  484.         XtDestroyWidget (toplevel);
  485.         XtAppAddWorkProc (XtWidgetToApplicationContext (gw),
  486.                   ExitWorkProc, (XtPointer) NULL);
  487.     }
  488.  
  489.     Boolean
  490.     ExitWorkProc (closure)
  491.         XtPointer    closure;
  492.     {
  493.         exit (0);
  494.         /*NOTREACHED*/
  495.     }
  496.  
  497.  
  498. ExitCallback() adds a work procedure that will get called when the
  499. application is next idle -- which happens after all the events are
  500. processed and the destroy callbacks are executed.
  501.  
  502. ----------------------------------------------------------------------
  503. 11. How do I resize a Shell widget?
  504. ----------------------------------------------------------------------
  505.  
  506. After it is realized, one doesn't resize a Shell widget.  The proper
  507. thing is to resize the currently managed child of the Shell widget
  508. using XtSetValues().  The geometry change is then propagated to the
  509. Shell which asks the window manager which may or may not allow the
  510. request.  However, the Shell must have the resource
  511. XtNallowShellResize set to True otherwise it will not even ask the
  512. window manager to grant the request and the Shell will not resize.
  513.  
  514. To change the position of a Shell, use XtSetValues() on the Shell, not
  515. the child, and within the limits of the window manager it should be granted.
  516.  
  517. ----------------------------------------------------------------------
  518. 12. Why can't XtAppAddInput() handle files?
  519. ----------------------------------------------------------------------
  520.  
  521. It does, however Unix semantics for when I/O is ready for a file does
  522. not fit most peoples' intuitive model.  In Unix terms a file
  523. descriptor is ready for reading whenever the read() call would not
  524. block, ignoring the setting of optional flags that indicate not to
  525. block.  This works as expected for terminals, sockets and pipes.  For
  526. a file the read() will always return but the return indicates an EOF
  527. -- i.e. no more data.  The result is the code in the Intrinsics always
  528. calls the input handler because it always thinks something is about to
  529. be read.  The culprit is the select() system call or on SYSV based
  530. OS's it is the poll() system call.
  531.  
  532. How to get around this on a Unix system?  The best approach is to use
  533. another process to check for available input on the file.  Use a pipe
  534. to connect the application with this other process and pass the file
  535. descriptor from the pipe to XtAppAddInput().  A suitable program on
  536. BSD systems is "tail -f filename".
  537.  
  538. It's rumored that select() on some systems is not _completely_
  539. reliable.  In particular:
  540.  
  541.     - IBM AIX 3.1: this is one where it would work for a while
  542.       (several thousand times) and then stop until some other
  543.       event woke it up. This seemed to be the result of a race
  544.       condition in the Kernel.  IBM claims to have a fix for this.
  545.  
  546.     - Pyramid, doesn't work at all.
  547.  
  548.     - Ultrix (and possibly others where pipes are implemented as
  549.       sockets), wasn't completely broken, but although the writing
  550.       side wrote in 512 byte blocks the reading side received it
  551.       all broken up as if it was being put into the pipe a byte at
  552.       a time.  You can waste a lot of time by reading small blocks
  553.       (get raound it by detecting the situation and having
  554.       select() ignore the pipe for 10 mseconds - by then it had
  555.       been given the whole block).
  556.  
  557.  
  558. Note that all the above descriptions used Unix terminology such as
  559. read(), file descriptor, pipes, etc.  This is an OS dependent area and
  560. may not be identical on all systems.  However the Intrinsic designers
  561. felt it was a common enough operation that it should be included with
  562. part of the toolkit.  Why they didn't also deal with signals at this
  563. point I don't know.
  564.  
  565. ----------------------------------------------------------------------
  566. 13. What good books and magazines are there on Xt?
  567. ----------------------------------------------------------------------
  568.  
  569. I have a favorite that is the definitive reference.  To my perspective
  570. it offers a reasonable introduction but also goes into the full
  571. details of the Intrinsics.  When I started using it I was already
  572. familiar with Xt and the concepts behind it, so newcomers may or may
  573. not find it useful.  I've always found it accurate and complete, which
  574. means its a 1000 pages.
  575.  
  576. Asente, Paul J., and Swick, Ralph R., "X Window System Toolkit, The
  577.     Complete Programmer's Guide and Specification", Digital Press,
  578.     1990, ISBN 1-55558-051-3, order number EY-E757E-DP; and by
  579.     Prentice-Hall, ISBN 0-13-972191-6. Also available through DEC
  580.     Direct at 1-800-DIGITAL.
  581.  
  582. The other book I commonly recomend to novices is:
  583.  
  584. Young, Doug. "The X Window System: Applications and Programming with
  585.     Xt (Motif Version)," Prentice Hall, 1989 (ISBN 0-13-497074-8).
  586.     (ISBN 0-13-972167-3)
  587.  
  588. And of course O'Reilly has an entire series of manuals on X and Xt.
  589. O'Reilly ordering is 800-998-9938.  In particular, Volume 5 is an Xt
  590. reference done in manual page style.  The 3rd edition is extensively
  591. overhauled and goes far beyond the MIT manual pages.  I'm finding it
  592. very useful.  In particular, the permutted index and references to
  593. other manual pages help a great deal in chasing down related
  594. information.
  595.  
  596. I read two periodicals, "The X Resource" and the "The X Journal".
  597. These are the only two dealing specifically with X.  "The X Resource"
  598. is published quarterly, by O'Reilly, with one of the issues being the
  599. MIT X Consortium Technical Conference Proceedings.  There is no
  600. advertising.  I've found it informative with pretty good depth.  For
  601. orders, call 1-800-998-9938, or email cathyr@ora.com.  For editorial
  602. matters, email adrian@ora.com.  Table of contents are posted at
  603. math.utah.edu in ~ftp/pub/tex/bib in TeX form and on ftp.uu.net in
  604. ~ftp/published/oreilly/xresource in ASCII form.
  605.  
  606.  
  607. "The X Journal" is a bimonthly trade rag with lots of advertising.
  608. The articles are informative and oriented toward a less technical
  609. audience.  I read it more to see what's going on then with an
  610. expectation of learning a great deal (but remember, I represent a
  611. fairly small percentage of people).  Also, they have a pretty good
  612. collection of people on the advisory board and as columnists.  Call
  613. (908) 563-9033.
  614.  
  615. ----------------------------------------------------------------------
  616. 14. What Widgets are available?
  617. ----------------------------------------------------------------------
  618.  
  619. There are three popular widget sets:
  620.  
  621. Athena    - The set provided with X11.  This is sufficient for most
  622.       purposes but is on the ugly side.  Recently, a 3d look is
  623.       available for ftp on export.lcs.mit.edu:/contrib/Xaw3d.tar.Z.
  624. Motif    - From OSF available for a license fee and commonly shipped on
  625.       many workstation vendors platforms (almost everyone but
  626.       Sun).  It looks good and works well but personally I think
  627.       it is poorly implemented.
  628. OLIT    - The Open Look Intrinsics Toolkit is a set of widgets
  629.       implementing Sun's Open Look specification.  Developed by
  630.       AT&T.  I've never used it so can't comment on its quality.
  631.       I've heard rumours that it is a pain to actually get.
  632.  
  633. In addition the following collection of widgets are also available:
  634.  
  635. Xtra    - a library of widgets for sale from Graphical Software
  636.       Technology (310-328-9338).  It includes bar graph, stacked
  637.       bar graph, line graph, pie chart, xy plot, hypertext, help,
  638.       spreadsheet, and data entry form widgets.  I've never seen
  639.       them so I can't comment.
  640. FWF    - The Free Widget Foundation is attempting to collect a set of
  641.       freely available widgets.  Included are a Pixmap editor,
  642.       FileDialog, and a few others.  The current set of widgets
  643.       can be obtained via anonymous ftp from the machine
  644.       a.cs.uiuc.edu (128.174.252.1) in the file pub/fwf.shar.Z.
  645. Xcu    - The Cornell University widgets from Gene Dykes.  One of the
  646.       early widget sets released.  Provides a nice appearance for
  647.       buttons and has a mini command language.  Probably not so
  648.       widely used.
  649. Xs    - The Sony widget set.  This was around during R3 days but
  650.       seemed to disappear.  It looked like it had promise.
  651. Xw    - The HP widgets.  The precursor to Motif.  Originally written
  652.       for R3 there exists diffs to get it to work under R4 & R5.
  653.       Again, a pretty good widget set but has more or less died.
  654.       The precursor to this was the Xray toolkit which was
  655.       originally implemented for X10R4 and apparently provided
  656.       much experience for the designers of Xt.
  657. Xo    - A widget set I'm working on.  It's still primitive but you
  658.       can give it a try in archive.cis.ohio-state.edu:pub/Xo/*
  659.  
  660. The following specialized widgets are also available:
  661.  
  662. Tbl    - Implements a tabular layout of widgets.  Supports Motif
  663.       widgets as children.  Part of Wcl.
  664. Plots    - The Athena Plotting widgets (not the Athena widgets).
  665.       Contact gnb@bby.oz.au or joe@Athena.MIT.EDU.
  666.  
  667. ----------------------------------------------------------------------
  668. 15. What alternatives to the Intrinsics are there?
  669. ----------------------------------------------------------------------
  670.  
  671.     __________________________________________
  672.     Name        Language    Vendor
  673.     __________________________________________
  674.     Xview        C        Sun
  675.     OI        C++        ParcPlace
  676.     Interviews    C++        Stanford
  677.     __________________________________________
  678.  
  679.  
  680. However much I like C and admire the skill in both designing and
  681. implementing the Intrinsics, hopefully some alternative will develop
  682. in the next 3-5 years that uses an object oriented language.  Keep
  683. your eyes open and expect some change about the same time a language
  684. other than C _starts_ gaining acceptance.
  685.  
  686. ----------------------------------------------------------------------
  687. 16. How do I pass a float value to XtSetValues?
  688. ----------------------------------------------------------------------
  689.  
  690. First, what is going wrong is the structure for an Arg is (essentially)
  691.     typdef struct
  692.     {    
  693.         String    name;
  694.         long    value;
  695.     } Arg;
  696.  
  697. and the code:
  698.     Arg    arg;
  699.  
  700.     XtSetArg (arg, "name", 3.2)
  701.  
  702. expands to
  703.     Arg    arg;
  704.  
  705.     arg.name = "name";
  706.     arg.value = 3.2;
  707.  
  708. you can see that with normal C type conversions, the arg.value
  709. gets the integer "3" instead of the floating point value "3.2".  When
  710. the value is copied into the widget resource, the bit pattern is
  711. wildly different than that required for a floating point value.  So,
  712. how to get around this?
  713.  
  714. The following macro is from the Athena widgets document and I am now
  715. recomending it over the previous suggestions.
  716.  
  717. #define XtSetFloatArg(arg, n, d) \
  718.     if (sizeof(float) > sizeof(XtArgVal)) { \
  719.         XtSetArg(arg, n, &(d)); \
  720.     } else { \
  721.         XtArgVal *ld = (XtArgVal *)&(d); \
  722.         XtSetArg(arg, n, *ld); \
  723.     }
  724.  
  725.  
  726. ----------------------------------------------------------------------
  727. 17. +++How do I write a resource converter?
  728. ----------------------------------------------------------------------
  729.  
  730. See section 9.6 of the Xt specification, and/or, start with a
  731. previously written resource converter, and modify it.
  732.  
  733. ----------------------------------------------------------------------
  734. 18. How do I open multiple displays?
  735. ----------------------------------------------------------------------
  736.  
  737. See "Multi-user Application Software Using Xt", The X Resource, Issue 3,
  738. (Summer 1992) by Oliver Jones for a complete coverage of the issues
  739. involved.  Most of this answer is based on that article.  In a
  740. nutshell, one uses XtOpenDisplay() to add each display to a _single_
  741. application context and then XtCloseDisplay() to shutdown each display
  742. and remove it from the application context.
  743.  
  744. The real problems occur when trying to close down a display.  This can
  745. happen 3 ways:
  746.     1. User selects a "quit" button on one of the displays,
  747.     2. User has window manager send a WM_DELETE_WINDOW message,
  748.     3. Server disconnect -- possibly from a KillClient message,
  749.        server shutdown/crash, or network failure.
  750.  
  751. I'll assume you can deal gracefully with 1 & 2 since it is _merely_ a
  752. problem of translating a Widget to a display and removing that
  753. display.  If not, then read the Oliver Jones article.
  754.  
  755. The third one is difficult to handle.  The following is based on the
  756. Oliver Jones article and I include it here because it is a difficult
  757. problem.
  758.  
  759. The difficulty arises because the Xlib design presumed that an I/O
  760. error is always unrecoverable and so fatal.  This is essentially true
  761. for a single display X based application, but not true for a
  762. multiple display program or an application that does things other than
  763. display information on an X server.  When an X I/O error occurs the
  764. I/O error handler is called and _if_ it returns then an exit()
  765. happens.  The only way around this is to use setjmp/longjmp to avoid
  766. returning to the I/O error handler.  The following code fragment
  767. demonstrates this:
  768.  
  769. #include <setjmp.h>
  770. jmp_buf XIOrecover;
  771.  
  772. void
  773. XIOHandler (dpy)
  774.     Display        *dpy;
  775. {
  776.     destroyDisplay (dpy);
  777.     longjmp (XIOrecover, 1);
  778. }
  779.  
  780. main ()
  781. {
  782.     ...
  783.     if (setjmp (XIOrecover) == 0)
  784.         XSetIOErrorHandler (XIOHandler);
  785.     XtAppMainLoop (app_context);
  786. }
  787.  
  788. The destroyDisplay() is something that given a Display pointer can go
  789. back to the application specific data and perform any necessary
  790. cleanup.  It should also call XtCloseDisplay().
  791.  
  792. For those of you unfamiliar with setjmp/longjmp, when setjmp() is
  793. first called it returns a 0 and save's enough information in the
  794. jmp_buf that a latter execution of longjmp() can return the program to
  795. the same state as if the setjmp() was just executed.  The return value
  796. of this second setjmp() is the value of the second argument to
  797. longjmp().  There are several caveats about using these but for this
  798. purpose it is adequate.
  799.  
  800. Some other problems you might run into are resource converters that
  801. improperly cache resources.  The most likely symptoms are Xlib errors
  802. such as BadColor, BadAtom, or BadFont.  There may be problems with the
  803. total number of displays you can open since typically only a limited
  804. number of file descriptors are available with 32 being a typical
  805. value.  You may also run into authorization problems when trying to
  806. connect to a display.
  807.  
  808. There was much discussion in comp.windows.x about this topic in
  809. November of 91.  Robert Scheifler posted an article which basically
  810. said this is the way it will be and Xlib will not change.
  811.  
  812. ----------------------------------------------------------------------
  813. 19. What changed from R3 to R4 to R5?
  814. ----------------------------------------------------------------------
  815.  
  816. This addresses only changes in the Intrinsics.  First, the general
  817. changes for each release are described.  Then a, certainly incomplete,
  818. list of new functions added and others that are now deprecated are
  819. listed.  Brevity is a primary goal.
  820.  
  821. Much of the following information is retrieved from Chapter 13 of the MIT
  822. Xt Intrinsics Manual and from O'Reilly Volume 5, 3rd edition.
  823.  
  824. From R3 to R4
  825. - Addition of gadgets (windowless widgets)
  826. - New resource type converter interface to handle cacheing and
  827.   additional  data.
  828. - Variable argument list interface.
  829. - #define XtSpecificationRelease 4  (added with this release)
  830. - WMShellPart, TopLevelShellPart & TransientShellPart changed
  831.   incompatibly.
  832. - core.initialize, core.set_values added ArgList and count parameters
  833. - event handlers had continue_to_dispatch parameter added
  834. - core.set_values_almost specification changed.
  835. - core.compress_exposure changed to an enumerated data type from Boolean
  836. - core.class_inited changed to enumerated data type from Boolean
  837. - constraint.get_values_hook added to extension record
  838. - core.initialize_hook obsolete as info is passed to core.initialize
  839. - shell.root_geometry_manager added to extension record
  840. - core.set_values_hook obsolete as info is passed to core.set_values
  841. - Calling XtQueryGeometry() must store complete geometry.
  842. - Added UnrealizeCallback.
  843. - XtTranslateCoords() actually works under R4.
  844.  
  845. From R4 to R5:
  846. - Psuedo resource baseTranslation added.
  847. - Searching for app-default, and other files, made more flexible
  848. - customization resource added.
  849. - Per-screen resource database.
  850. - Support permanently allocated strings.
  851. - Permanetly allocated strings required for several class fields.
  852. - The args argument to XtAppInitialize, XtVaAppInitialize,
  853.   XtOpenDisplay, XtDisplayInitialize, and XtInitialize were changed
  854.   from Cardinal* to int*
  855. - Many performance improvements (this is summarized from the article
  856.   "Xt Performance Improvements in Release 5" by Gabe Beged-Dov in "The
  857.   X Resource", Issue 3):
  858.     - XrmStringToQuark() augmented with XrmPermStringToQuark() to
  859.       avoid string copies.  Several fields in the class record are
  860.       indicated as needing permanent strings.
  861.     - Using an array of Strings for resources
  862.     - Callback lists redesigned to use less memory
  863.     - Translation manager redesigned and rewritten so it takes
  864.       less memory, translation tables merges are faster, cache of
  865.       action bindings
  866.     - Keycode to Keysyms are cached.
  867.     - Better sharing of GC's with modifiable fields
  868.     - Window to Widget translation uses less space and faster
  869.     - Does not malloc space for widget name since quark is available
  870.     - Widget space is allocated to include the constraints
  871.     - Over several example programs, about a 26% reduction in
  872.       memory usage.
  873.  
  874. Functions new with R5:
  875. ----------------------
  876. XtAllocateGC()        - sharable GC with modifiable fields  
  877. XtGetActionList()    - get the action table of a class
  878. XtScreenDatabase()    - return resource database for a screen
  879. XtSetLanguageProc()    - register language procedure called to set locale
  880.  
  881.  
  882. Functions new with R4:
  883. ----------------------
  884. XtAppAddActionHook()    - procedure to call before _every_ action.
  885. XtAppInitialize()    - lots of initialization work.
  886. XtAppReleaseCacheRefs()    - decrement cache reference count for converter
  887. XtAppSetFallbackResources() - specify default resources
  888. XtAppSetTypeConverter()    - register a new style converter
  889. XtCallCallbackList()    - directly execute a callback list
  890. XtCallConverter    ()    - invoke a new style converter
  891. XtCallbackReleaseCacheRef() - release a cached resource value
  892. XtCallbackReleaseCacheRefList() - release a list of cached resource values
  893. XtConvertAndStore()    - find and call a resource converter
  894. XtDirectConvert()    - Invoke old-style converter
  895. XtDisplayOfObject()    - Return the display
  896. XtDisplayStringConversionWarning() - issue a warning about conversion
  897. XtFindFile()        - Find a file
  898. XtGetActionKeysym()    - Retrieve keysym & modifies for this action
  899. XtGetApplicationNameAndClass() - return name and class
  900. XtGetConstraintResourceList() - get constraints for a widget
  901. XtGetKeysymTable()    - return keycode-to-keysym mapping table
  902. XtGetMultiClickTime()    - read the multi-click time
  903. XtGetSelectionRequest()    - retrieve the SelectionRequest event
  904. XtGetSelectionValueIncremental() - obtain the selection value incrementally
  905. XtGetSelectionValuesIncremental() - obtain the selection value incrementally
  906. XtInitializeWidgetClass() - initialize a widget class manually
  907. XtInsertEventHanlder()    - register event handler before/after others
  908. XtInsertRawEventHandler() - register event handler without modify input mask
  909. XtIsObject()        - test if subclass of Object
  910. XtIsRectObj()        - test if subclass of RectObj
  911. XtKeysymToKeyCodeList()    - return list of keycodes
  912. XtLastTimestampProcessed() - retrieve most recent event time
  913. XtMenuPopdown        - Action for popping down a widget
  914. XtMenuPopup        - Action for popping up a widget
  915. XtOffsetOf        - macro for structure offsets
  916. XtOwnSelectionIncremental() - make selection data availabe incrementally
  917. XtPoupSpringLoaded()    - map a spring-loaded popup
  918. XtRegisterGrabAction()    - indicate action procedure needs a passive grab
  919. XtRemoveActiohHook()    - remove function called after every action
  920. XtResolvePathname()    - find a file
  921. XtScreenOfObject()    - return screen of object.
  922. XtSetMultiClickTime()    - set the multi-click time
  923. XtSetWMColormapWindows() - set WM_COLORMAP_WINDOWS for custom colormaps
  924. XtUngrabButton()    - cancel a passive button grab
  925. XtUngrabKey()        - cancel a passive key grab
  926. XtUngrabKeybard()    - release an active keyboard grab
  927. XtUngrabPointer()    - release an active pointer grab
  928. XtVa*()            - varags interfaces to a bunch of functions
  929. XtWindowOfObject()    - return Window of nearest widget ancestor
  930.  
  931.  
  932. Deprecated        Replacement            When
  933. ----------------------------------------------------------------------
  934. XtAddActions()        XtAppAddActions()        R3
  935. XtAddConverter()    XtAppAddConverter()        R3
  936. XtAddInput()        XtAppAddInput ()        R3
  937. XtAddTimeout()        XtAppAddTimeout()        R3
  938. XtAddWorkProc()        XtAppAddWorkProc()        R3
  939. XtConvert()        XtConvertAndStore()        R4
  940. XtCreateApplicationShell XtAppCreateShell()        R3
  941. XtDestroyGC()        XtReleaseGC()            R3
  942. XtError()        XtAppError()            R3
  943. XtGetErrorDatabase()    XtAppGetErrorDatabase        R3
  944. XtGetErrorDatabaseText() XtAppGetErrorDatabaseText    R3
  945. XtGetSelectionTimeout()    XtAppGetSelectionTimeout    R3
  946. XtInitialize()        XtAppInitialize()        R3
  947. XtMainLoop()        XtAppMainLoop()            R3
  948. MenuPopdown(action)    XtMenuPopdown(action)        R4
  949. MenuPopup(action)    XtMenuPopup(action)        R4
  950. XtNextEvent()        XtAppNextEvent()        R3
  951. XtPeekEvent()        XtAppPeekEvent()        R3
  952. XtPending()        XtAppPending()            R3
  953. XtSetErrorHandler()    XtAppSetErrorHandler()        R3
  954. XtSetErrorMsgHandler    XtAppSetErrorMsgHandler()    R3
  955. XtSetSelectionTimeout()    XtAppSetSelectionTimeout()    R3
  956. XtSetWarningHandler()    XtAppSetWarningHandler()    R3
  957. XtSetWarningMsgHandler() XtAppSetWarningMsgHandler()    R3
  958. XtWarning()        XtAppWarning()            R3
  959. XtWarningMsg()        XtAppWarningMsg()        R3
  960.  
  961. ----------------------------------------------------------------------
  962. 20. Where are the resources loaded from?
  963. ----------------------------------------------------------------------
  964.  
  965. The resources of a widget are filled in from the following places
  966. (from highest priority to lowest priority):
  967.  
  968.     1. Args passed at creation time.
  969.     2. Command line arguments.
  970.     3. User's per host defaults file
  971.     4. User's defaults file.
  972.     5. User's per application default file.
  973.     6. System wide per application default file.
  974.  
  975. Note that 2-6 are read only once on application startup.  The result
  976. of steps 3-6 is a single resource database used for further queries.
  977.  
  978. The per host defaults file contains customizations for all
  979. applications executing on a specific computer.  This file is either
  980. specified with the XENVIRONMENT environment variable or if that is not
  981. set then the file $HOME/.Xdefaults-<host> is used.
  982.  
  983. The user defaults file is either obtained from the RESOURCE_MANAGER
  984. property on the root window of the display or if that is not set then
  985. the file $HOME/.Xdefaults is used.  Typically, the program "xrdb" is
  986. used to set the RESOURCE_MANAGER property.  Please note that this
  987. should be kept relatively small as each client that connects to the
  988. display must transfer the property.  A size of around 1-3KByte is
  989. reasonable.  Some toolkits may track changes to the RESOURCE_MANAGER
  990. but most do not.
  991.  
  992. A user may have many per application default files containing
  993. customizations specific to each application.  The intrinsics are quite
  994. flexible on how this file is found.  Read the next part that describes
  995. the various environment variables and how they effect where this file
  996. is found.
  997.  
  998. The system wide per application default files are typically found in
  999. /usr/lib/X11/app-defaults.  If such a file is not found then the
  1000. fallback resources are used.  The intrinsics are quite flexible on how
  1001. this file is found.  Read the next part that describes the various
  1002. environment variables and how they effect where this file is found.
  1003.  
  1004. [Thanks to Oliver Jones (oj@pictel.com) for the following, 6/92]
  1005.  
  1006. You can use several environment variables to control how resources are
  1007. loaded for your Xt-based programs -- XFILESEARCHPATH,
  1008. XUSERFILESEARCHPATH, and XAPPLRESDIR.  These environment variables
  1009. control where Xt looks for application-defaults files as an
  1010. application is initializing.  Xt loads at most one app-defaults file
  1011. from the path defined in XFILESEARCHPATH and another from the path
  1012. defined in XUSERFILESEARCHPATH.
  1013.  
  1014. Set XFILESEARCHPATH if software is installed on your system in such a
  1015. way that app-defaults files appear in several different directory
  1016. hierarchies.  Suppose, for example, that you are running Sun's Open
  1017. Windows, and you also have some R4 X applications installed in
  1018. /usr/lib/X11/app-defaults. You could set a value like this for
  1019. XFILESEARCHPATH, and it would cause Xt to look up app-defaults files
  1020. in both /usr/lib/X11 and /usr/openwin/lib (or wherever your
  1021. OPENWINHOME is located):
  1022.  
  1023.     setenv XFILESEARCHPATH /usr/lib/X11/%T/%N:$OPENWINHOME/lib/%T/%N
  1024.  
  1025. The value of this environment variable is a colon-separated list of
  1026. pathnames.  The pathnames contain replacement characters as follows
  1027. (see XtResolvePathname()):
  1028.  
  1029.     %N    The value of the filename parameter, or the
  1030.         application's class name.
  1031.     %T    The value of the file "type".  In this case, the
  1032.         literal string "app-defaults"
  1033.     %C    customization resource (R5 only)
  1034.     %S    Suffix.  None for app-defaults.
  1035.     %L    Language, locale, and codeset (e.g. "ja_JP.EUC")
  1036.     %l    Language part of %L  (e.g. "ja")
  1037.     %t    The territory part of the display's language string
  1038.     %c    The codeset part of the display's language string
  1039.  
  1040. Let's take apart the example.  Suppose the application's class name is
  1041. "Myterm". Also, suppose Open Windows is installed in /usr/openwin.
  1042. (Notice the example omits locale-specific lookup.)
  1043.  
  1044.     /usr/lib/X11/%T/%N        means /usr/lib/X11/app-defaults/Myterm
  1045.     $OPENWINHOME/lib/%T/%N    means /usr/openwin/lib/app-defaults/Myterm
  1046.  
  1047. As the application initializes, Xt tries to open both of the above
  1048. app-defaults files, in the order shown.  As soon as it finds one, it
  1049. reads it and uses it, and stops looking for others.  The effect of
  1050. this path is to search first in /usr/lib/X11, then in /usr/openwin.
  1051.  
  1052. Let's consider another example. This time, let's set
  1053. XUSERFILESEARCHPATH so it looks for the file Myterm.ad in the current
  1054. working directory, then for Myterm in the directory ~/app-defaults.
  1055.  
  1056.     setenv XUSERFILESEARCHPATH ./%N.ad:$HOME/app-defaults/%N
  1057.  
  1058. The first path in the list expands to ./Myterm.ad.  The second expands
  1059. to $HOME/app-defaults/Myterm.  This is a convenient setting for
  1060. debugging because it follows the Imake convention of naming the
  1061. app-defaults file Myterm.ad in the application's source directory, so
  1062. you can run the application from the directory in which you are
  1063. working and still have the resources loaded properly.
  1064.  
  1065. NOTE: when looking for app-default files with XUSERFILESEARCHPATH,
  1066.       for some  bizarre reason, neither the type nor file suffix is
  1067.       defined so %T and %S are useless.
  1068.  
  1069. With R5, there's another twist.  You may specify a customization
  1070. resource value.  For example, you might run the "myterm" application
  1071. like this:
  1072.  
  1073.     myterm -xrm "*customization: -color"
  1074.  
  1075. If one of your pathname specifications had the value
  1076. "/usr/lib/X11/app-defaults/%N%C" then the expanded pathname would be
  1077. "/usr/lib/X11/app-defaults/Myterm-color" because the %C substitution
  1078. character takes on the value of the customization resource.
  1079.  
  1080. The default XFILESEARCHPATH, compiled into Xt, is:
  1081.  
  1082.         /usr/lib/X11/%L/%T/%N%C:\  (R5)
  1083.         /usr/lib/X11/%l/%T/%N%C:\  (R5)
  1084.         /usr/lib/X11/%T/%N%C:\     (R5)
  1085.         /usr/lib/X11/%L/%T/%N:\
  1086.         /usr/lib/X11/%l/%T/%N:\
  1087.         /usr/lib/X11/%T/%N
  1088.  
  1089. (Note: some sites replace /usr/lib/X11 with a ProjectRoot in this
  1090. batch of default settings.)
  1091.  
  1092. The default XUSERFILESEARCHPATH, also compiled into Xt, is 
  1093.  
  1094.         <root>/%L/%N%C:\  (R5)
  1095.         <root>/%l/%N%C:\  (R5)
  1096.         <root>/%N%C:\     (R5)
  1097.         <root>/%L/%N:\
  1098.         <root>/%l/%N:\
  1099.         <root>/%N:
  1100.  
  1101. <root> is either the value of XAPPLRESDIR or the user's home directory
  1102. if XAPPLRESDIR is not set.  If you set XUSERFILESEARCHPATH to some
  1103. value other than the default, Xt ignores XAPPLRESDIR altogether.
  1104.  
  1105. Notice that the quick and dirty way of making your application find
  1106. your app-defaults file in your current working directory is to set
  1107. XAPPLRESDIR to ".", a single dot.  In R3, all this machinery worked
  1108. differently; for R3 compatibilty, many people set their XAPPLRESDIR
  1109. value to "./", a dot followed by a slash.
  1110.  
  1111.  
  1112. ----------------------------------------------------------------------
  1113. 21. What order are callbacks executed in?
  1114. ----------------------------------------------------------------------
  1115. (Courtesy of Donna Converse, converse@expo.lcs.mit.edu; 5/10/92)
  1116.  
  1117. The Intrinsics library do not guarantee an order.  This is because
  1118. both the widget writer and the application writer have the ability to
  1119. modify the entire contents of the callback list.  Neither one
  1120. currently knows what the other is doing and so the Intrinsics cannot
  1121. guarantee the order of execution.
  1122.  
  1123. The application programmer cannot rely on the widget writer; the
  1124. widget writer is not required to document when the widget will add and
  1125. remove callbacks from the list or what effect this will have;
  1126. therefore the functionality contained in a callback should be
  1127. independent of the functionality contained in other callbacks on the
  1128. list.
  1129.  
  1130. Even though the Xt standard in the definition of XtAddCallback
  1131. says:
  1132.  
  1133.      "callback_name: Specifies the callback list to which the
  1134.      procedure is to be appended."
  1135.  
  1136. you may not infer from the word "appended" that the callback routines
  1137. are called in the same order as they have been added to the callback
  1138. list.
  1139.  
  1140. ----------------------------------------------------------------------
  1141. 22. How do I know if a widget is visible?
  1142. ----------------------------------------------------------------------
  1143. (Courtesy of Donna Converse, converse@expo.lcs.mit.edu; 5/14/92)
  1144.  
  1145. > I am building a widget needs to know if it is visible. I set the visible
  1146. > interest field in Core and if my window is completely obscured, the Core
  1147. > visible flag goes FALSE. However, if my window is iconified, the flag
  1148. > stays set to TRUE.
  1149.  
  1150. Right, everything is implemented correctly.  This demonstrates a "deficiency"
  1151. in the X protocol, and the Core widget is reflecting the capabilities of the
  1152. protocol.  (The "deficiency" is that the information is available in one way,
  1153. in this case an inconvenient way.)  The Xt specification is accurate, in
  1154. the second and third paragraphs of section 7.10.2, so read this section
  1155. carefully.  The visible field will not change in response to iconification.
  1156.  
  1157. A VisibilityNotify event will not be received when the window goes from
  1158. viewable to unviewable, that is, when the widget or an ancestor is unmapped;
  1159. that is, when iconification occurs.  This is the protocol deficiency.
  1160. Visibility state and viewable state have specific meanings in the X protocol;
  1161. see the glossary in your Xlib and X protocol reference manual.
  1162.  
  1163. > Is this a problem with "mwm" or is there something
  1164. > else which needs to be done?
  1165.  
  1166. You'll see this with any window manager, with no window manager.
  1167.  
  1168. > If the problem is "mwm", what is the fastest
  1169. > way to determine if a window is iconified? 
  1170.  
  1171. As an application writer, keep track with a global Boolean in an action
  1172. routine with translations for MapNotify and UnmapNotify on the Shell widget
  1173. which contains your custom widget.  As the custom widget writer, see the
  1174. map_state field returned by a call to XGetWindowAttributes.  These are
  1175. suggestions.
  1176.  
  1177. ----------------------------------------------------------------------
  1178. 23. How do I reparent a widget in Xt, i.e. XtReparentWidget()?
  1179. ----------------------------------------------------------------------
  1180.  
  1181. You can't.
  1182.  
  1183. ----------------------------------------------------------------------
  1184. 24. Why use XtMalloc, XtFree, etc?
  1185. ----------------------------------------------------------------------
  1186.  
  1187. Unfortunately, most code that calls malloc(), realloc() or calloc()
  1188. tends to ignore the possibility of returning NULL.  At best it is
  1189. handled something like:
  1190.  
  1191.     ptr = (type *) malloc (sizeof (type))
  1192.     if (!ptr)
  1193.     {
  1194.         perror ("malloc in xyzzy()");
  1195.         exit (1)
  1196.     }
  1197. To handle this common case the Intrinsics define the functions
  1198. XtMalloc(), XtCalloc(), XtNew(), XtNewString() and XtRealloc() which
  1199. all use the standard C language functions malloc(), calloc() and
  1200. realloc() but execute XtErrorMsg() if a NULL value is returned.  Xt
  1201. error handlers are not supposed to return so this effectively exits.
  1202.  
  1203. In addition, if XtRealloc() is called with a NULL pointer, it uses
  1204. XtMalloc() to get the initial space.  This allows code like:
  1205.  
  1206.     if (!ptr)
  1207.         ptr = (type *) malloc (sizeof (type));
  1208.     else
  1209.         ptr = (type *) realloc (ptr, sizeof (type) * (count + 1));
  1210.     ++count;
  1211.  
  1212. to be written as:
  1213.  
  1214.     ptr = XtRealloc (ptr, sizeof (ptr) * ++count);
  1215.  
  1216. Also, XtFree() accepts a NULL pointer as an argument.  Generally, I've
  1217. found the Xt functions conveniant to use.  However, anytime I'm
  1218. allocating anything potentially large I use the standard functions so
  1219. I can fully recover from not enough memory errors.
  1220.  
  1221. XtNew() and XtNewString() are conveniant macros for allocating a
  1222. structure or copying a string:
  1223.  
  1224.       struct abc *xyzzy;
  1225.       char         *ptr;
  1226.       char         *str = "abcdef";
  1227.  
  1228.       xyzzy = XtNew (struct abc);    /* takes care of type casting */
  1229.       ptr = XtNewString (str);
  1230.  
  1231. Just to emphasize this, the Xt memory allocators are required to be
  1232. compatible and so interchangeable with the standard C library memory
  1233. allocators.
  1234.  
  1235. A common error for Motif programmers is to use XtFree() on a string
  1236. when they should really be using XmStringFree().
  1237.  
  1238. ----------------------------------------------------------------------
  1239. 25. How to debug an Xt application?
  1240. ----------------------------------------------------------------------
  1241. First, I'd recomend getting "purify" from Pure Software.  This is a
  1242. great package for tracing memory problems on Sun's.  It's a bit pricey
  1243. at $2750 but I'd still recomend it.  Excuse the marketing blurb
  1244. (contact support@pure.com for more info).
  1245.  
  1246.     Purify inserts additional checking instructions directly into
  1247.     the object code produced by existing compilers.  These
  1248.     instructions check every memory read and write performed by
  1249.     the program under test and detect several types of access
  1250.     errors, such as reading unitialized memory, writing past
  1251.     malloc'd bounds, or writing to freed memory.  Purify inserts
  1252.     checking logic into all of the code in a program, including
  1253.     third party and vendor object-code libraries, and verifies
  1254.     system call interfaces.  In addition, Purify tracks memory
  1255.     usage and identifies individual memory leaks using a novel
  1256.     adaption of garbage collection techniques.  Purify's nearly
  1257.     comprehensive memory access checking slows the target program
  1258.     down typically by a factor of two to five.
  1259.  
  1260. An alternative package that isn't as pricey ($395 for a Sun), runs on
  1261. many Unix's and has pretty similar features is "The SENTINEL Debugging
  1262. Environment".  This replaces malloc() and several other C library
  1263. functions to add additional checks.  (contact cpcahil@virtech.vti.com
  1264. for more info)
  1265.  
  1266. Next, if you are getting any sort of Xlib error, you'll need to run in
  1267. synchronous mode, easily accompished with the "-sync" command line
  1268. argument or by setting the variable Xdebug to 1 with your debugger.  Then
  1269. set a break point in exit().  This will let you trace back to the
  1270. original Xlib function being called.  If you don't run in synchronous
  1271. mode, then the actual error may have occured any number of calls to
  1272. Xlib previously since the Xlib calls are buffered and replies from the
  1273. server are asynchronous.
  1274.  
  1275. Next, if you are having trouble with window layout, you can use the
  1276. undocumented resource "xtIdentifyWindows" or the class resource
  1277. "XtDebug" to cause the widget name to be identified with each window.
  1278. For example:
  1279.  
  1280.     example% xload -xrm '*XtDebug:true' &
  1281.     example% xwininfo -tree
  1282.          <click in new xload window>
  1283.  
  1284. will give the normal information but the widget name and class of each
  1285. window is included.  This can help for checking the location and size
  1286. of errant widgets.
  1287.  
  1288. Next, if you are having trouble with geometry managers or you want to
  1289. test the way a widget manages it's children, you can try
  1290. export.lcs.mit.edu:contrib/libXtGeo.tar.Z.  This acts as a filter
  1291. between any children and a geometry manager and checks the behaviour
  1292. of both.  It's a very clever idea.
  1293.  
  1294. The most unfortunate problem is debugging a callback while the
  1295. application is executing a grab of the keyboard or mouse (such as from
  1296. a pulldown menu).  The server effectively locks up and you'll need to
  1297. go to another machine and kill the debugger manually.  The server
  1298. locks up because the application being debugged has said no one else
  1299. can have access to the keyboard but the application is not stopped
  1300. waiting because the debugger is waiting for your commands.
  1301. Unfortunately you can't give them because all the input is going to
  1302. your application which is stopped.
  1303.  
  1304. The best way to debug this kind of problem is with two machines on
  1305. your desk, running the program under a debugger (or other environment)
  1306. on one machine, and running the application on the other, possibly
  1307. using a command sequence like this:
  1308.  
  1309.     othermachine% xhost +thismachine
  1310.     thismachine% setenv DISPLAY othermachine:0;
  1311.     thismachine% gdb application    # Your favorite debugger.
  1312.     or this:
  1313.     othermachine% xhost +thismachine
  1314.     thismachine% gdb application
  1315.     (gdb) set environment DISPLAY othermachine:0
  1316.     (gdb) run ...
  1317.  
  1318. I believe CodeCenter, a C interpreter/graphical debugger has a method
  1319. of dealing with this by explicitely calling the Xlib functions to
  1320. release any grabs during breakpoints.
  1321.  
  1322. Debugging widget problems requires pretty good debugging skills and
  1323. knowledge of how widgets work.  You can go a long way without knowing
  1324. the internals of a particular widget but not very far without
  1325. understanding how a widget works.  Judicious use of conditional
  1326. breakpoints and adding print statements with the debugger help a great
  1327. deal.
  1328.  
  1329. ----------------------------------------------------------------------
  1330. 26. Why don't XtAddInput(), XtAddTimeout() and XtAddWorkProc() work?
  1331. ----------------------------------------------------------------------
  1332.    I have got a delicate problem with the three routines XtAddInput,
  1333.    XtAddTimeOut and XtAddWorkProc. The problem I have is that when
  1334.    I use them in my application they seem not to be registred properly.
  1335.    I have made a handy little testprogram where everything works
  1336.    perfect, but in my "real" application nothing happens. 
  1337.  
  1338. The introduction in R3 of the XtApp*() functions obsoleted those
  1339. routines.  What happens is they use a default application context
  1340. different then the one you may have created.  Since events and
  1341. timeouts are distributed on a per application context basis and you
  1342. are using two application contexts, you won't get those events.
  1343.  
  1344. For example:
  1345.  
  1346.     ...
  1347.     cnt = 0;
  1348.     toplevel = XtAppInitialize(&app, class,
  1349.                    Desc, XtNumber (Desc),
  1350.                    &argc, argv,
  1351.                    Fallback, args, cnt);
  1352.  
  1353.     XtAddTimeOut (...)
  1354.     XtAddWorkProc (...)
  1355.  
  1356.     XtAppMainLoop (app)
  1357.  
  1358. would never invoke the timeout.
  1359.  
  1360. -- 
  1361. Pete Ware / Ohio State University /        228 Bolz Hall  (614) 292-7318
  1362.            ware@cis.ohio-state.edu        2036 Neil Ave.
  1363.            (h) (614) 538-0965            Columbus, OH 43210
  1364. Welcome William Patrick Ware to the world!  Born 10/21/92, 8lbs 6.2oz (3.83kg)
  1365.